import { Injector } from "../inject";
import { EventDispatcher } from "./EventDispatcher";


type Constructor<T = unknown> = new (...args: any[]) => T;


function rewrite(constructor: Constructor, onKey: string, offKey: string, onSuper: boolean = true): void {
    let onFunc = constructor.prototype[onKey];
    let offFunc = constructor.prototype[offKey];
    constructor.prototype[onKey] = function () {
        let dispatcher: EventDispatcher = Injector.default.getInstance('EventDispatcher');
        dispatcher.targetOn(this, onSuper);
        onFunc && onFunc.call(this);
    }
    constructor.prototype[offKey] = function () {
        let dispatcher: EventDispatcher = Injector.default.getInstance('EventDispatcher');
        dispatcher.targetOff(this);
        offFunc && offFunc.call(this);
    }
}

/**
 * 装饰器  修饰类OnLoad时注入事件
 * @param onSuper 
 * @returns 
 */
export function eventsOnLoad(onSuper: boolean = true): Function {
    return function (constructor: Constructor) {
        rewrite(constructor, 'onLoad', 'onDestroy', onSuper);
    };
}


/**
 * 装饰器  修饰类OnEnable时注入事件
 * @param onSuper
 * @returns 
 */
export function eventsOnEnable(onSuper: boolean = true): Function {
    return function (constructor: Constructor) {
        rewrite(constructor, 'onEnable', 'onDisable', onSuper);
    };
}

/**
 * 装饰器  修饰函数，载入事件，类修饰为EventsOnLoad或EventsOnEnable才注册成功
 * @param event 
 * @param once 
 * @returns 
 */
export function registerEvent(event: string, once: boolean = false): Function {
    return function (target: any, funcName: string, descriptor: PropertyDescriptor) {
        let dispatcher: EventDispatcher = Injector.default.getInstance('EventDispatcher');
        dispatcher.registerEvents(target.constructor, event, funcName, once);
    };
}

export { EventDispatcher } from "./EventDispatcher";

